home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / polyview / polyvw31.lha / Polyview3.1 / new / pvray.c < prev    next >
C/C++ Source or Header  |  1993-06-23  |  23KB  |  788 lines

  1. /*****************************************************************************
  2.  * NCSA Polyview 3.0                                                         *
  3.  *                                                                           *
  4.  * Version 3 changes and additions by Marc Andreessen.                       *
  5.  * Version 2 by Brian Calvert.                                               *
  6.  *                                                                           *
  7.  * Software Development Group                                                *
  8.  * National Center for Supercomputing Applications                           *
  9.  * University of Illinois at Urbana-Champaign                                *
  10.  *                                                                           *
  11.  * This is BETA release software.  As such it may contain software bugs and  *
  12.  * exhibit inconsistencies.                                                  *
  13.  *                                                                           *
  14.  * Please send bug reports to polyview@ncsa.uiuc.edu.                        *
  15.  *                                                                           *
  16.  * Copyright (c) 1992 The Board of Trustees of the University of Illinois.   *
  17.  *                                                                           *
  18.  * Permission to use, copy, and modify this software and its                 *
  19.  * documentation for educational, research, and non-profit purposes is       *
  20.  * hereby granted, provided that the above copyright notice, the original    *
  21.  * authors names, and this permission notice appear in all such copies.      *
  22.  * Any distribution of this software requires the explicit and written       *
  23.  * authorization of the authors.                                             *
  24.  *                                                                           *
  25.  * The University of Illinois makes no representations about the             *
  26.  * suitability of this software for any purpose.  It is provided "as is"     *
  27.  * without warranty of any kind.                                             *
  28.  *****************************************************************************/
  29.  
  30. /* $Header: /usr3/people/gbourhis/pv3/new/RCS/pvray.c,v 1.1 92/09/18 10:55:26 marca Exp $ */
  31.  
  32. #ifdef RCSLOG
  33. $Log:    pvray.c,v $
  34.  * Revision 1.1  92/09/18  10:55:26  marca
  35.  * Initial revision
  36.  * 
  37. #endif
  38.  
  39. #include "pv.h"
  40.  
  41. /* ------------------------------------------------------------------------ */
  42. /* ----------------------- RAYSHADE OUTPUT ROUTINES ----------------------- */
  43. /* ------------------------------------------------------------------------ */
  44.  
  45. static FILE *rayfp = NULL;
  46.  
  47. static void ray_bgnpolygon (void)
  48. {
  49.   fprintf (rayfp, "  poly \n");
  50.   
  51.   return;
  52. }
  53.  
  54. static void ray_v3f (float *vv)
  55. {
  56.   fprintf (rayfp, "    %f %f %f\n", vv[0], vv[1], vv[2]);
  57.   
  58.   return;
  59. }
  60.  
  61. static void ray_endpolygon (void)
  62. {
  63.   
  64.   return;
  65. }
  66.  
  67. static void ray_palettecpack (int c)
  68. {
  69.   fprintf (rayfp, "    pal%1d\n", c);
  70.   
  71.   return;
  72. }
  73.  
  74.  
  75. /* Keep a static array of vertices and a count of the number
  76.    of vertices in the array. */
  77. static float line_vv[20][3];
  78. static int line_vv_count = 0;
  79.  
  80. static int line_cc[20];
  81. static int line_cc_used = 0;
  82.  
  83. /* Static width of lines drawn as cylinders. */
  84. static float line_width = 0.1;
  85.  
  86. /* This should be a window-local variable or something. */
  87. static int cap_cylinders = 0;
  88.  
  89. static void ray_linepalettecpack (int c)
  90. {
  91.   /* Save this color index with the current vertex. */
  92.   line_cc[line_vv_count] = c;
  93.  
  94.   /* Note that we are using colors for this line. */
  95.   line_cc_used = 1;
  96. }
  97.  
  98. static void ray_bgnclosedline (void)
  99. {
  100.   /* Starting a new line. */
  101.   line_vv_count = 0;
  102.   
  103.   /* Haven't used any colors yet. */
  104.   line_cc_used = 0;
  105. }
  106.  
  107. static void ray_endclosedline (void)
  108. {
  109.   int i;
  110.  
  111.   /* If we have one or fewer vertices, punt. */
  112.   if (line_vv_count < 2)
  113.     goto done;
  114.  
  115.   /* For each vertex up to the second-to-last, make
  116.      a cylinder with the vertex and its successor. */
  117.   for (i = 0; i < line_vv_count - 1; i++)
  118.     {
  119.       fprintf (rayfp, "  cylinder\n");
  120.  
  121.       if (line_cc_used)
  122.         {
  123.           /* We've used colors, so set a color. */
  124.           fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  125.         }
  126.  
  127.       fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  128.                /* radius */ "CYL_RAD",
  129.                /* end 1  */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
  130.                /* end 2  */ line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2]);
  131.  
  132.       if (cap_cylinders)
  133.         {
  134.           fprintf (rayfp, "  disc\n");
  135.           if (line_cc_used)
  136.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  137.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  138.                    "CYL_RAD",
  139.                    line_vv[i][0], line_vv[i][1], line_vv[i][2],
  140.                    line_vv[i][0] - line_vv[i+1][0],
  141.                    line_vv[i][1] - line_vv[i+1][1],
  142.                    line_vv[i][2] - line_vv[i+1][2]);
  143.           fprintf (rayfp, "  disc\n");
  144.           if (line_cc_used)
  145.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  146.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  147.                    "CYL_RAD",
  148.                    line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2],
  149.                    line_vv[i+1][0] - line_vv[i][0],
  150.                    line_vv[i+1][1] - line_vv[i][1],
  151.                    line_vv[i+1][2] - line_vv[i][2]);
  152.         }
  153.     }
  154.  
  155.   /* If there's more than 2 vertices, close the line. */
  156.   if (line_vv_count > 2)
  157.     {
  158.       i = line_vv_count - 1;
  159.       
  160.       fprintf (rayfp, "  cylinder\n");
  161.       
  162.       if (line_cc_used)
  163.         {
  164.           fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  165.         }
  166.       
  167.       fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  168.                /* radius */ "CYL_RAD",
  169.                /* end 1  */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
  170.                /* end 2  */ line_vv[0][0], line_vv[0][1], line_vv[0][2]);
  171.       
  172.       if (cap_cylinders)
  173.         {
  174.           fprintf (rayfp, "  disc\n");
  175.           if (line_cc_used)
  176.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  177.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  178.                    "CYL_RAD",
  179.                    line_vv[i][0], line_vv[i][1], line_vv[i][2],
  180.                    line_vv[i][0] - line_vv[0][0],
  181.                    line_vv[i][1] - line_vv[0][1],
  182.                    line_vv[i][2] - line_vv[0][2]);
  183.           fprintf (rayfp, "  disc\n");
  184.           if (line_cc_used)
  185.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  186.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  187.                    "CYL_RAD",
  188.                    line_vv[0][0], line_vv[0][1], line_vv[0][2],
  189.                    line_vv[0][0] - line_vv[i][0],
  190.                    line_vv[0][1] - line_vv[i][1],
  191.                    line_vv[0][2] - line_vv[i][2]);
  192.         }
  193.     }
  194.   
  195.  done:
  196.   line_vv_count = 0;
  197.   return;
  198. }
  199.  
  200.  
  201. static void ray_linev3f (float *vv)
  202. {
  203.   /* Store this vertex. */
  204.   line_vv[line_vv_count][0] = vv[0];
  205.   line_vv[line_vv_count][1] = vv[1];
  206.   line_vv[line_vv_count][2] = vv[2];
  207.  
  208.   /* Increment the count. */
  209.   line_vv_count++;
  210.  
  211.   return;
  212. }
  213.  
  214.  
  215. /* ------------------------------------------------------------------------ */
  216. /* ------------------------ SPHERE RAY/GL ROUTINES ------------------------ */
  217. /* ------------------------------------------------------------------------ */
  218.  
  219. static float sphere_size;
  220.  
  221. /* 1 if vertices should be drawn as cubes. */
  222. static int sphere_cubes;
  223.  
  224. static int sphere_col_set = 0;
  225. static int sphere_col;
  226.  
  227. static void ray_sphpalettecpack (int c)
  228. {
  229.   sphere_col_set = 1;
  230.   sphere_col = c;
  231.  
  232.   return;
  233. }
  234.  
  235.  
  236. static void ray_sphdraw (float *vv)
  237. {
  238.   if (sphere_cubes)
  239.     {
  240.       fprintf (rayfp, "  box\n");
  241.       if (sphere_col_set)
  242.         fprintf (rayfp, "    pal%1d\n", sphere_col);
  243.       fprintf (rayfp, "    (%f-SPH_RAD) (%f-SPH_RAD) (%f-SPH_RAD)\n",
  244.                vv[0],
  245.                vv[1],
  246.                vv[2]);
  247.       fprintf (rayfp, "    (%f+SPH_RAD) (%f+SPH_RAD) (%f+SPH_RAD)\n",
  248.                vv[0],
  249.                vv[1],
  250.                vv[2]);
  251.     }
  252.   else
  253.     {
  254.       fprintf (rayfp, "  sphere\n");
  255.       if (sphere_col_set)
  256.         fprintf (rayfp, "    pal%1d\n", sphere_col);
  257.       fprintf (rayfp, "    %s\n", "SPH_RAD");
  258.       fprintf (rayfp, "    %f %f %f\n", vv[0], vv[1], vv[2]);
  259.     }
  260.  
  261.   /* Make sure we don't repeat a color. */
  262.   sphere_col_set = 0;
  263.  
  264.   return;
  265. }
  266.  
  267.  
  268.  
  269.  
  270. static int ray_draw_vertices (state_t *state, window_t *win, object_t *obj, 
  271.                            objinfo_t *info)
  272. {
  273.   long    count;
  274.   
  275.   Vdata_t **vdata;
  276.   Vdata_t *vcolor_v;
  277.   Vdata_t *pcoord_v;
  278.   
  279.   float    (*pcoord)[DIMS];
  280.   int *vcolor;
  281.   char *picked;
  282.  
  283.   int single_color;
  284.   
  285.   /* Get pointers to the pertinent data sets */
  286.   vdata = obj->u.obj.vdata;
  287.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  288.   if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  289.     return ST_OKAY;
  290.  
  291.   /* Set up the consolidated coordinate array pointer. */
  292.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  293.   count = pcoord_v->stats[0].rec_count;
  294.   assert (pcoord_v->stats[0].type == PVFLOAT);
  295.  
  296.   if (FEQ(win->sphere_size, 0.0))
  297.     sphere_size = win->max_width * 0.01;
  298.   else
  299.     sphere_size = win->sphere_size;
  300.  
  301.   fprintf (rayfp, "#define SPH_RAD %f\n", sphere_size);
  302.  
  303.   sphere_cubes = (win->sphere_depth == 1);
  304.  
  305.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  306.     {
  307.       /* No color information.  Use foreground and draw the */
  308.       /* appropriate shapes. */
  309.       while (count > 0) 
  310.         {
  311.           { /* not selected */
  312.             float params[4];
  313.             
  314.             params[0] = (*pcoord)[0];
  315.             params[1] = (*pcoord)[1];
  316.             params[2] = (*pcoord)[2];
  317.             params[3] = win->sphere_size;
  318.             
  319.             ray_sphdraw (params);
  320.           }
  321.           
  322.           /* Move to the next x, y, z set and decrement the */
  323.           /* count. */
  324.           pcoord++;
  325.           count--;
  326.         }
  327.     }
  328.   else 
  329.     {
  330.       /* Set pointers to the actual data and the size of the data */
  331.       /* sets. */
  332.       assert (vcolor_v->stats[0].type == PVINTEGER);
  333.       
  334.       /* There is color information.  Get it and use it to draw the */
  335.       /* appropriate shapes. */
  336.       vcolor = (int *) vcolor_v->data;
  337.       
  338.       while (count > 0) 
  339.         {
  340.           { /* not selected */
  341.             float params[4];
  342.             
  343.             ray_sphpalettecpack(*vcolor);
  344.             
  345.             params[0] = (*pcoord)[0];
  346.             params[1] = (*pcoord)[1];
  347.             params[2] = (*pcoord)[2];
  348.             params[3] = win->sphere_size;
  349.             
  350.             ray_sphdraw (params);      
  351.           }
  352.           /* Move to the next x, y, z set, color entry, and */
  353.           /* decrement the count. */
  354.           pcoord++;
  355.           vcolor++;
  356.           count--;
  357.         }
  358.     }
  359.  
  360.   return ST_OKAY;
  361. }
  362.  
  363. static int ray_draw_edges (state_t *state, window_t *win, object_t *obj, 
  364.                            objinfo_t *info)
  365. {
  366.   long count;
  367.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  368.   float (*pcoord)[DIMS];
  369.   int *vcolor, *connect;
  370.   char *picked;
  371.   int i, nvert, vertex;
  372.  
  373.   /* Set the width of the cylinders. */
  374.   line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
  375.  
  376.   fprintf (rayfp, "#define CYL_RAD %f\n", line_width);
  377.  
  378.   /* Get pointers to the pertinent data sets. */
  379.   vdata = obj->u.obj.vdata;
  380.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  381.   if ((connect_v = get_vdata(state, vdata[CONNECT])) == NULL) 
  382.     if ((connect_v = get_vdata(state, vdata[MCONNECT])) == NULL) 
  383.       {
  384.         ray_draw_vertices(state, win, obj, info);
  385.         return ST_OKAY;
  386.       }
  387.   if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  388.     return ST_OKAY;
  389.   
  390.   /* Collect connectivity information for drawing. */
  391.   connect = (int *) connect_v->data;
  392.   count = connect_v->stats[0].rec_count;
  393.   nvert = connect_v->stats[0].rec_size;
  394.   
  395.   /* Set up the consolidated coordinate array pointer. */
  396.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  397.   assert (pcoord_v->stats[0].type == PVFLOAT);
  398.   
  399.   /* If there is no vertex color information, draw without it */
  400.   /* (use the FOREGROUND color).  Otherwise, grab the color array. */
  401.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  402.     {
  403.       /* No color information.  Use foreground and draw the */
  404.       /* appropriate shapes. */
  405.       while (count > 0) 
  406.         {
  407.           ray_bgnclosedline();
  408.           
  409.           for (i = nvert; i > 0; i--) 
  410.             {
  411.               if ( (vertex = *(connect++)-1) == -1) 
  412.                 {
  413.                   connect += i-1;
  414.                   break;
  415.                 }
  416.               ray_linev3f(pcoord[vertex]);
  417.             }
  418.           
  419.           ray_endclosedline();
  420.           
  421.           count--;
  422.         }
  423.     }
  424.   else 
  425.     {
  426.       /* Set pointers to the actual data and the size of the data */
  427.       /* sets. */
  428.       assert (vcolor_v->stats[0].type == PVINTEGER);
  429.       
  430.       /* There is color information.  Get it and use it to draw the */
  431.       /* appropriate shapes. */
  432.       vcolor = (int *) vcolor_v->data;
  433.       while (count > 0) 
  434.         {
  435.           ray_bgnclosedline();
  436.           
  437.           for (i = nvert; i > 0; i--) 
  438.             {
  439.               if ( (vertex = *(connect++)-1) == -1) 
  440.                 {
  441.                   connect += i-1;
  442.                   break;
  443.                 }
  444.  
  445.               ray_linepalettecpack(vcolor[vertex]);
  446.               ray_linev3f(pcoord[vertex]);
  447.             }
  448.           
  449.           ray_endclosedline();
  450.           
  451.           count--;
  452.         }
  453.     }
  454.  
  455.   return ST_OKAY;
  456. }
  457.  
  458.  
  459. static int ray_draw_faces (state_t *state, window_t *win, object_t *obj, 
  460.                            objinfo_t *info)
  461. {
  462.   long count;
  463.   
  464.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  465.     
  466.   float    (*pcoord)[DIMS];
  467.   int *vcolor, *connect;
  468.   char *picked;
  469.   
  470.   int i, nvert, vertex, single_color;
  471.   
  472.   /* Get pointers to the pertinent data sets */
  473.   vdata = obj->u.obj.vdata;
  474.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  475.   if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
  476.     if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
  477.       return ray_draw_vertices(state, win, obj, info);
  478.   
  479.   /* If the plist does not describe polygons, draw edges. */
  480.   if (connect_v->stats[0].rec_size < 3)
  481.     return ray_draw_edges(state, win, obj, info);
  482.   
  483.   if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  484.     return ST_OKAY;
  485.   
  486.   /* Collect connectivity information for drawing. */
  487.   connect = (int *) connect_v->data;
  488.   count = connect_v->stats[0].rec_count;
  489.   nvert = connect_v->stats[0].rec_size;
  490.   
  491.   /* Set up the consolidated coordinate array pointer. */
  492.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  493.   assert (pcoord_v->stats[0].type == PVFLOAT);
  494.   
  495.   /* If there is no vertex color information, draw without it */
  496.   /* (use the FOREGROUND color).  Otherwise, grab the color array. */
  497.  
  498.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  499.     {
  500.       while (count > 0) 
  501.         {
  502.           ray_bgnpolygon();
  503.           for (i = nvert; i > 0; i--) 
  504.             {
  505.               if ( (vertex = *(connect++)-1) == -1) 
  506.                 {
  507.                   connect += i-1;
  508.                   break;
  509.                 }
  510.               ray_v3f(pcoord[vertex]);
  511.             }
  512.           ray_endpolygon();
  513.           
  514.           count--;
  515.         }
  516.     }
  517.   else 
  518.     {
  519.       /* Set pointers to the actual data and the size of the data */
  520.       /* sets. */
  521.       assert (vcolor_v->stats[0].type == PVINTEGER);
  522.       
  523.       /* There is color information.  Get it and use it to draw the */
  524.       /* appropriate shapes. */
  525.       vcolor = (int *) vcolor_v->data;
  526.  
  527.       while (count > 0) 
  528.         {
  529.           ray_bgnpolygon();
  530.           for (i = nvert; i > 0; i--) 
  531.             {
  532.               if ((vertex = *(connect++)-1) == -1) 
  533.                 {
  534.                   connect += i-1;
  535.                   break;
  536.                 }
  537.               
  538.               if (i == nvert)
  539.                 ray_palettecpack (vcolor[vertex]);
  540.  
  541.               ray_v3f(pcoord[vertex]);
  542.             }
  543.           ray_endpolygon();
  544.           
  545.           count--;
  546.         }
  547.  
  548.     }
  549.   
  550.   return ST_OKAY;
  551. }
  552.  
  553.  
  554.  
  555. static int ray_draw_outlined_faces(state_t *state, window_t *win, 
  556.                                    object_t *obj,
  557.                                    objinfo_t *info)
  558. {
  559.   long count;
  560.   
  561.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  562.   
  563.   float (*pcoord)[DIMS];
  564.   float pcoord_outline[DIMS];
  565.   int *vcolor, *connect, *oconnect;
  566.   char *picked;
  567.   int i, j, nvert, vertex, single_color;
  568.  
  569.   /* Set the width of the cylinders. */
  570.   line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
  571.  
  572.   fprintf (rayfp, "#define CYL_RAD %f\n", line_width);
  573.  
  574.   /* Get pointers to the pertinent data sets */
  575.   vdata = obj->u.obj.vdata;
  576.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  577.   if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL) 
  578.     if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL) 
  579.       return ray_draw_vertices(state, win, obj, info);
  580.  
  581.   /* If the plist does not describe polygons, draw edges. */
  582.   if (connect_v->stats[0].rec_size < 3)
  583.     return ray_draw_edges(state, win, obj, info);
  584.   
  585.   if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  586.     return ST_OKAY;
  587.   
  588.   /* Collect connectivity information for drawing. */
  589.   oconnect = connect = (int *) connect_v->data;
  590.   count = connect_v->stats[0].rec_count;
  591.   nvert = connect_v->stats[0].rec_size;
  592.   
  593.   /* Set up the consolidated coordinate array pointer. */
  594.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  595.   
  596.   assert (pcoord_v->stats[0].type == PVFLOAT);
  597.   
  598.   /* If there is no vertex color information, draw without it. */
  599.   /* Otherwise, grab the color array. */
  600.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  601.     {
  602.       while (count > 0)
  603.         {
  604.           /* Save connectivity pointer. */
  605.           oconnect = connect;
  606.           
  607.           /* Draw the polygon. */
  608.           ray_bgnpolygon();
  609.           for (i = nvert; i > 0; i--) 
  610.             {
  611.               if ( (vertex = *(connect++)-1) == -1) 
  612.                 {
  613.                   connect += i-1;
  614.                   break;
  615.                 }
  616.               
  617.               ray_v3f(pcoord[vertex]);
  618.             }
  619.           ray_endpolygon();
  620.           
  621.           /* Start connectivity anew. */
  622.           connect = oconnect;
  623.           
  624.           /* Draw the outline of the polygon, with Z values */
  625.           ray_bgnclosedline();
  626.           for (i = nvert; i > 0; i--) 
  627.             {
  628.               if ( (vertex = *(connect++)-1) == -1)
  629.                 {
  630.                   connect += i-1;
  631.                   break;
  632.                 }
  633.               ray_linev3f(pcoord[vertex]); 
  634.             }
  635.           ray_endclosedline();
  636.           
  637.           count--;
  638.         }
  639.       
  640.     }
  641.   else 
  642.     {
  643.       /* Set pointers to the actual data and the size of the data */
  644.       /* sets. */
  645.       assert (vcolor_v->stats[0].type == PVINTEGER);
  646.       
  647.       /* There is color information.  Get it and use it to draw the */
  648.       /* appropriate shapes. */
  649.       vcolor = (int *) vcolor_v->data;
  650.  
  651.       while (count > 0) 
  652.         {
  653.           /* Save connectivity pointer. */
  654.           oconnect = connect;
  655.           
  656.           /* Draw the polygon. */
  657.           ray_bgnpolygon();
  658.           for (i = nvert; i > 0; i--) 
  659.             {
  660.               if ( (vertex = *(connect++)-1) == -1) 
  661.                 {
  662.                   connect += i-1;
  663.                   break;
  664.                 }
  665.               if (i == nvert)
  666.                 ray_palettecpack(vcolor[vertex]);
  667.               ray_v3f(pcoord[vertex]);
  668.             }
  669.           ray_endpolygon();
  670.           
  671.           /* Start connectivity anew. */
  672.           connect = oconnect;
  673.           
  674.           /* Draw the outline of the polygon, with Z values */
  675.           ray_bgnclosedline();
  676.           for (i = nvert; i > 0; i--) 
  677.             {
  678.               if ( (vertex = *(connect++)-1) == -1)
  679.                 {
  680.                   connect += i-1;
  681.                   break;
  682.                 }
  683.               ray_linev3f(pcoord[vertex]); 
  684.             }
  685.           ray_endclosedline();
  686.           
  687.           count--;
  688.         }
  689.       
  690.     }
  691.   
  692.   return ST_OKAY;
  693. }
  694.  
  695.  
  696.  
  697. void dump_ray (state_t *state, window_t *win, char *fname)
  698. {
  699.   polyview_t *pv;
  700.   object_t *obj;
  701.   int i;
  702.  
  703.   assert (win->type == POLYVIEW);
  704.   pv = (polyview_t *)WIN_IMAGE(win);
  705.  
  706.   rayfp = fopen (fname, "w");
  707.   if (rayfp == NULL)
  708.     {
  709.       stprintf (state, "Could not open output file.");
  710.       return;
  711.     }
  712.  
  713.   fprintf (rayfp, "/* NCSA Polyview 3.0 rayshade output file. */\n\n");
  714.   fprintf (rayfp, "/* National Center for Supercomputing Applications */\n");
  715.   fprintf (rayfp, "/* University of Illinois at Urbana-Champaign */\n");
  716.   fprintf (rayfp, "/* polyview@ncsa.uiuc.edu */\n\n");
  717.  
  718.   fprintf (rayfp, "eyep %f %f %f\n", win->cfrom[X], win->cfrom[Y],
  719.            win->cfrom[Z]);
  720.   fprintf (rayfp, "lookp %f %f %f\n", win->at[X], win->at[Y], win->at[Z]);
  721.   fprintf (rayfp, "up 0 -1 0\n\n");
  722.  
  723.   fprintf (rayfp, "background 0 0 0\n\n");
  724.   fprintf (rayfp, "screen %d %d\n\n", pv->dv_width, pv->dv_height);
  725.  
  726.   /* default light is directional, intensity 1.0, (1 -1 1). */
  727.   fprintf (rayfp, "light 1.0 point %f %f %f\n\n",
  728.            win->cfrom[X] * 1.5, win->cfrom[Y] * 1.5, win->cfrom[Z] * 1.5);
  729.  
  730.   if (WIN_DRAW(win) == DrawTrans)
  731.     fprintf (rayfp, "#define TRANSP_COEF 0.4\n");
  732.   if (WIN_DRAW(win) == draw_vertices)
  733.     fprintf (rayfp, "#define REFL_COEF 0.5\n");
  734.   
  735.   for (i = 0; i < 256; i++)
  736.     {
  737.       fprintf (rayfp, 
  738.                "surface pal%1d\n  ambient %f %f %f\n  diffuse %f %f %f\n",
  739.                i,
  740.                (float)state->pal[i][0]/760.0,
  741.                (float)state->pal[i][1]/760.0,
  742.                (float)state->pal[i][2]/760.0,
  743.                (float)state->pal[i][0]/255.0,
  744.                (float)state->pal[i][1]/255.0,
  745.                (float)state->pal[i][2]/255.0);
  746.       if (WIN_DRAW(win) == DrawTrans)
  747.         fprintf (rayfp, "  transp TRANSP_COEF\n");
  748.       if (WIN_DRAW(win) == draw_vertices)
  749.         fprintf (rayfp, "  reflect REFL_COEF\n");
  750.     }
  751.  
  752.   fprintf (rayfp, "\n");
  753.  
  754.   if (WIN_FRAME(win) == NULL)
  755.     {
  756.       assert (WIN_FRAMELIST(win) == NULL);
  757.       return;
  758.     }
  759.  
  760.   obj = FRA_ROOTOBJ (WIN_FRAME(win));
  761.  
  762.   /* Make sure that the object exists, has information associated */
  763.   /* with it, and has a drawing function. */
  764.   assert (obj != NULL);
  765.   assert (obj->info != NULL);
  766.   assert (obj->info->draw_fn != NULL);
  767.   
  768.   fprintf (rayfp, "grid 8 8 8\n");
  769.  
  770.   if (WIN_DRAW(win) == draw_faces)
  771.     ray_draw_faces (state, win, obj, obj->info);
  772.   if (WIN_DRAW(win) == draw_edges)
  773.     ray_draw_edges (state, win, obj, obj->info);
  774.   if (WIN_DRAW(win) == draw_outlined_faces || WIN_DRAW(win) == DrawTrans ||
  775.       WIN_DRAW(win) == draw_hidden_edges)
  776.     ray_draw_outlined_faces (state, win, obj, obj->info);
  777.   if (WIN_DRAW(win) == draw_vertices)
  778.     ray_draw_vertices (state, win, obj, obj->info);
  779.  
  780.   fprintf (rayfp, "end /* grid */\n");
  781.  
  782.   fclose (rayfp);
  783.  
  784.   rayfp = NULL;
  785.  
  786.   return;
  787. }
  788.